//
//  map.cpp
//  RPG
//
//  Created by Matt Bailey on 03/01/2014.
//  Copyright (c) 2014 Matt Bailey. All rights reserved.
//

int mikuX = 0, mikuY = 0;

#include "map.hpp"

void Map::init() {
    
    width = (Window::getWidth() / tileWidth) + (bufferSize * 2);
    height = (Window::getHeight() / tileWidth) + (bufferSize * 2);

    cout << width << height << endl;
    
    world.init("insert string here");
    
    createTileIndex();
    generateUVCoords();
    
    tileSet = Graphics::loadPNG("Resources/Textures/tileset.png");
    
    vertexBuffer = Graphics::createVBO(generateVertexData());

}

void Map::update() {
   
    int newTileX = (int)Camera::getPosX() / tileWidth;
    int newTileY = (int)Camera::getPosY() / tileWidth;
    
    int diffX = Camera::getrefX() / tileWidth - newTileX;
    int diffY = Camera::getrefY() / tileWidth - newTileY;
    
    // Relocate Somewhere
    if (diffX >= threshold) {   // Left
        Camera::translateCamera(threshold * tileWidth, 0);
        generateUVCoords();
    }
    
    if (diffX <= -threshold) {  // Right
        Camera::translateCamera(-threshold * tileWidth, 0);
        generateUVCoords();
    }
    
    if (diffY >= threshold) {   // Up
        Camera::translateCamera(0, threshold * tileWidth);
        generateUVCoords();
    }
    
    if (diffY <= -threshold) {  // Down
        Camera::translateCamera(0, -threshold * tileWidth);
        generateUVCoords();
    }
}

void Map::generateUVCoords() {
    
    int x, y, z;
    float t = (float)1 / (float)16;
    
    UVData.clear();
    
    int mikuX = Entities::miku.getPosition().x; int mikuY = Entities::miku.getPosition().y;
    
    /*
    if (mikuX < 0) {
        Entities::miku.setPosition(glm::vec2(0, mikuY));
    }
    
    if (mikuX > world.getWidth()) {
        Entities::miku.setPosition(glm::vec2(world.getWidth(), mikuY));    }
    
    if (mikuY < 0) {
        Entities::miku.setPosition(glm::vec2(mikuX, 0));
    }
    
    if (mikuY > world.getHeight()) {
        Entities::miku.setPosition(glm::vec2(mikuX, world.getHeight()));
    }*/
    
    
    float linearPosition = mikuX + (mikuY * world.getWidth());
    /*
    if (linearPosition > (world.getWidth() * world.getHeight())) {
        
        linearPosition = 0;
    }*/
    
    
    for (z = 0; z < height; z++) {
        
        for (x = 0; x < width; x++) {
        
            int tilePos = x + linearPosition + (z * world.getWidth());
            
            if (tilePos > (world.getWidth() * world.getHeight())) {
                tilePos -= (world.getWidth() * world.getHeight());
            }
            
        GLfloat hRatio = (float)(world.tileData[tilePos]) / (float)16;
        GLfloat vRatio = 0;
        
        cout << linearPosition << endl;
            
            //if (linearPosition > 0) {
            
        for (y = 0; y < 16; y++) {
            
            if ((hRatio <= y) && (hRatio > (y - 1))) {
                vRatio = (float)y / (float)16;
                hRatio -= y;
            }
        }
        
        UVData.push_back(glm::vec2(hRatio - t, vRatio - t));
        UVData.push_back(glm::vec2(hRatio, vRatio - t));
        UVData.push_back(glm::vec2(hRatio - t, vRatio));
            
        //----------------------------------------
            
        UVData.push_back(glm::vec2(hRatio, vRatio - t));
        UVData.push_back(glm::vec2(hRatio, vRatio));
        UVData.push_back(glm::vec2(hRatio - t, vRatio));
        }
       // }
    }
    
        UVBuffer = Graphics::createVBO(UVData); // Err no
    
}

vector<glm::vec2> Map::generateVertexData() {
    
    vector<glm::vec2> vertexData;
    vertexData.clear();
    
    int x, y;
    
    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            
            vertexData.push_back(glm::vec2(tileWidth * x, tileWidth * y));
            vertexData.push_back(glm::vec2(tileWidth * (x + 1), tileWidth * y));
            vertexData.push_back(glm::vec2(tileWidth * x, tileWidth * (y + 1)));
            
            //----------------------------------------
            
            vertexData.push_back(glm::vec2(tileWidth * (x + 1), tileWidth * y));
            vertexData.push_back(glm::vec2(tileWidth * (x + 1), tileWidth * (y + 1)));
            vertexData.push_back(glm::vec2(tileWidth * x, tileWidth * (y + 1)));
        }
    }

    return vertexData;
}

void Map::createTileIndex() {
    
    cout << "Creating Tile Index";
    stringstream ss;
    string line;
    
    ss.str("");
    ss << settings;
    
    while (getline(ss, line)) {
        
        stringstream ls(line);
        
        int id; string tileName;
        ls >> id >> tileName;
        
        tileName.erase(remove(tileName.begin(), tileName.end(), ',' ), tileName.end() );
        tileName.erase(remove(tileName.begin(), tileName.end(), '"' ), tileName.end() );
        
        if (id < 255) {
            Tile tempTile(tileName);
            tileIndex[id] = tempTile;
        }
        
        else {
            //cout << "WARNING: '" << tileName << "' ID out of Range\n";
        }
    }
    
    cout << "\t\t[ OK ]\n";
}

vector<Tile> Map::tileIndex(255);
Dimension Map::world;

vector<glm::vec2> Map::UVData;

string Map::rootDirectory;
string Map::settings;

GLuint Map::tileSet;
GLuint Map::vertexBuffer;
GLuint Map::UVBuffer;

int Map::tileWidth = 64;

int Map::threshold = 1; // Number of Tiles to pass before update
int Map::bufferSize = 2;

unsigned int Map::width;
unsigned int Map::height;

vector<int> Map::mapData = {
    
    1, 1, 2, 1, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3,
    1, 2, 17, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0,
    2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3, 1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0,
    0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0, 2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3,
    2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0, 2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3,
    2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0,
    2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3, 1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0,
    0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0, 2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3,
    2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    1, 2, 2, 1, 3, 2, 0, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 1, 0, 2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3,
    2, 2, 2, 1, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 2, 1, 0, 2, 1, 3, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 0, 1, 2, 3, 2, 3, 2, 1, 2, 3, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1,
    
};
